#ifndef STATSxx_DATASET_HPP
#define STATSxx_DATASET_HPP


// STL
#include <utility>                       // std::pair<>
#include <vector>                        // std::vector<>

// jScience
#include "jScience/linalg/Matrix.hpp"    // Matrix<double>

// stats++
#include "statsxx/dataset/DataPoint.hpp" // DataPoint
#include "statsxx/dataset/DataSet.hpp"   // DataSet


//========================================================================
//========================================================================
//
// NAME: void shuffle_data_set( DataSet &data_set )
//
// DESC: Shuffle a DataSet object.
//
// INPUT:
//     DataSet data_set      : Data set to be shuffled
//
// OUTPUT:
//     DataSet data_set      : Shuffled data set.
//
//========================================================================
//========================================================================
void shuffle_data_set( DataSet &data_set );
#include "statsxx/dataset/shuffle_data_set.cpp"


//========================================================================
//========================================================================
//
// NAME: std::vector<DataSet> partition_dataset( const DataSet &data_set, const std::vector<double> f )
//
// DESC: Partitions a DataSet object.
//
// INPUT:
//     DataSet dataset       : Data set to be partitioned
//     std::vector<double> f : Partition fractions [default of 80/20 for (training and validation)/testing, and 80/20 training/validation of the remaining]
//
// OUTPUT:
//     std::vector<DataSet> return_data_sets : Return data sets, partitioned according to f.
//
// NOTES:
//     ! f is normalized in partition_data(), it need not sum to 1, as passed.
//
//========================================================================
//========================================================================
std::vector<DataSet> partition_data_set( const DataSet &data_set, const std::vector<double> f = {0.64, 0.16, 0.2} );
#include "statsxx/dataset/partition_data_set.cpp"

//std::vector<DataSet> partition_dataset_ensemble( const DataSet &dataset, const unsigned int n, const std::vector<double> f = {0.64, 0.16, 0.2} );


//========================================================================
//
// NAME: void balance_training_set(TRAINING_SET &TS)
//
// DESC: Balances a classiciation training set, ensuring equal (almost, at least) proportions of output. For classification training sets ONLY.
//
//========================================================================
void balance_training_set(DataSet &TS);
#include "statsxx/dataset/balance_training_set.cpp"


//========================================================================
// NAME: void get_TS_stats(const DataSet &TS, std::vector<double> &inp_min,  std::vector<double> &inp_max,  std::vector<double> &inp_mean,  std::vector<double> &inp_var,  std::vector<double> &inp_stddev, std::vector<double> &out_min,  std::vector<double> &out_max,  std::vector<double> &out_mean,  std::vector<double> &out_var,  std::vector<double> &out_stddev )
// DESC: Calculates the statistical properties of a training set.
//========================================================================
void get_TS_stats(const DataSet &TS, std::vector<double> &inp_min,  std::vector<double> &inp_max,  std::vector<double> &inp_mean,  std::vector<double> &inp_var,  std::vector<double> &inp_stddev, std::vector<double> &out_min,  std::vector<double> &out_max,  std::vector<double> &out_mean,  std::vector<double> &out_var,  std::vector<double> &out_stddev );
#include "statsxx/dataset/get_TS_stats.cpp"


// CONVERSION TOOLS:

DataSet Matrix_to_DataSet(
                          const Matrix<double> &X,          // data
                          const Matrix<double> &X_out       // data (output)
                          );
#include "statsxx/dataset/Matrix_to_DataSet.cpp"

std::pair<
          Matrix<double>,
          Matrix<double>
          > DataSet_to_Matrix(
                              const DataSet &data_set
                              );
#include "statsxx/dataset/DataSet_to_Matrix.cpp"


#endif
